package com.nbst.comnutil;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author wangwt
 * @description http的工具类
 * @since 2020-07-22
 **/
public class HttpUtil {
    /**
     * 无IP限制
     */
    private static final String ALL_IP = "*";


    public static String getIpAddress(HttpServletRequest request) {
        String ip = null;

        //X-Forwarded-For：Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP：apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP：weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP：有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP：nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        //有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }

        //还是不能获取到，最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 当前IP的IP正则的校验
     * @param currentIp
     * @param ipRegex
     * @return
     */
    public static boolean checkIp(String currentIp,String ipRegex){
        if(ALL_IP.equals(ipRegex)){
            return true;
        }
        return Pattern.matches(ipRegex, currentIp);
    }


    /**
     * 校验IP名单
     * @param currentIp
     * @param ipList
     * @return
     */
    public static boolean checkIpList(String currentIp, List<String> ipList){
        if(ipList!=null && ipList.size()>0){
            for(String blackIp:ipList){
                if(checkIp(currentIp, blackIp)){
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 校验IP名单
     * @param currentIp
     * @param ipList
     * @return
     */
    public static boolean checkIpListNullEqTure(String currentIp, List<String> ipList){
        if(ipList!=null && ipList.size()>0){
            for(String blackIp:ipList){
                if(checkIp(currentIp, blackIp)){
                    return true;
                }
            }
        } else {
            //没有白名单就不做白名单校验
            return true;
        }
        return false;
    }

    /**
     * 校验黑白名单
     * @param ip
     * @param blackIpList 黑名单
     * @param whiteIpList 白名单
     * @return
     */
    public static boolean checkBlackWhiteIpList(String ip, List<String> blackIpList, List<String> whiteIpList){
        if(HttpUtil.checkIpListNullEqTure(ip, whiteIpList) &&
                !HttpUtil.checkIpList(ip, blackIpList)){
            return true;
        }
        return false;
    }
}
